package com.koron.css2.newProjectCenter.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.hutool.poi.excel.StyleSet;
import com.google.common.collect.MapDifference;
import com.google.common.collect.Maps;
import com.koron.css2.ExportInterface;
import com.koron.css2.baseConfig.bean.PrefStrategyBean;
import com.koron.css2.baseConfig.bean.WaterTypeBean;
import com.koron.css2.baseConfig.mapper.*;
import com.koron.css2.baseConfig.queryBean.WaterTypeQueryBean;
import com.koron.css2.baseConfig.vo.SelectVO;
import com.koron.css2.baseConfig.vo.WaterTypeVO;
import com.koron.css2.clientCenter.bean.AccountInfoBean;
import com.koron.css2.clientCenter.bean.CtmInfoBean;
import com.koron.css2.clientCenter.bean.UserBean;
import com.koron.css2.clientCenter.mapper.AccountInfoMapper;
import com.koron.css2.clientCenter.mapper.CtmInfoMapper;
import com.koron.css2.clientCenter.mapper.UserInfoMapper;
import com.koron.css2.clientCenter.queryBean.UserInfoQueryBean;
import com.koron.css2.common.utils.ExcelUtils;
import com.koron.css2.newProjectCenter.bean.PjInfoBean;
import com.koron.css2.newProjectCenter.bean.PjMeter;
import com.koron.css2.newProjectCenter.bean.query.PjMeterQuery;
import com.koron.css2.newProjectCenter.mapper.PjInfoMapper;
import com.koron.css2.newProjectCenter.mapper.PjMeterMapper;
import com.koron.css2.serviceManage.bean.RequestBean;
import com.koron.css2.serviceManage.bean.UserFieldBean;
import com.koron.css2.serviceManage.bean.UserInfoBean;
import com.koron.css2.serviceManage.mapper.PubAdminAreaMapper;
import com.koron.css2.serviceManage.mapper.UserFieldConfigMapper;
import com.koron.css2.serviceManage.utils.JsonUtils;
import com.koron.css2.serviceManage.vo.BusinessAreaVo;
import com.koron.css2.systemManage.mapper.OrgUserMapper;
import com.koron.util.Constant;
import com.koron.util.Tools;
import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.koron.ebs.mybatis.SessionFactory;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.swan.bean.MessageBean;

import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: ；lwc
 * @Date: 2023/10/26/18:51
 * @Description:
 */
@Slf4j
@Service
public class NewPjMeterRegisterAccountExport implements ExportInterface {
    @Override
    public HttpEntity<?> export(SessionFactory factory, UserInfoBean userInfo, RequestBean req) {
        ExcelWriter writer = ExcelUtil.getWriter();
        ByteOutputStream out = new ByteOutputStream();
        try {
            List<Map<String, Object>> list = getList(factory, userInfo, req);
            UserFieldConfigMapper userFieldConfigMapper = factory.getMapper(UserFieldConfigMapper.class);
            BusinessAreaMapper businessAreaMapper = factory.getMapper(BusinessAreaMapper.class);

            List<UserFieldBean> listUserFieldBean = userFieldConfigMapper.registerFindFieldNameByPageNameAndGroupCode("PjMeterDetail", userInfo.getCurWaterCode());
            Map<String,Integer> mandatoryMap=listUserFieldBean.stream().collect(Collectors.toMap(UserFieldBean::getFieldCode,a->a.getMandatory()));
            mandatoryMap.put("certNo",1);
            mandatoryMap.put("ctmName",1);
            mandatoryMap.put("ctmTypeName",1);
            mandatoryMap.put("certTypeName",1);
            mandatoryMap.put("payWayName",1);
            mandatoryMap.put("accountTypeNameD",1);
            mandatoryMap.put("vatFlagName",1);
            mandatoryMap.put("preInvoicingName",1);
            Map<String, Object> headers = title(listUserFieldBean);
            Iterator<String> iterator1 = headers.keySet().iterator();
           if (ObjectUtil.isNotEmpty(list)){
               while (iterator1.hasNext()){
                   String key = iterator1.next();
                   for (Map<String, Object> map : list) {
                    map.computeIfAbsent(key,x->"");
                   }

               }
           }
            String[] vatFlagNames={"是","否"};
            //客户类型
            Map<String, String> ctt = Tools.mapDicByCode(factory, "CTT");//E
            Map<String, String> idt = Tools.mapDicByCode(factory, "IDT");//证件类型 F
            Map<String, String> cdl = Tools.mapDicByCode(factory, "CDL");//信用等级 G
            Map<String, String> bpw = Tools.mapDicByCode(factory, "BPW");//缴费方式 K
            Map<String, String> act = Tools.mapDicByCode(factory, "ACT");//账户类型 L
            Map<String, String> SDW = Tools.mapDicByCode(factory, "SDW");//投递方式 M
            Map<String, String> bjms = Tools.mapDicByCode(factory, "BJMS");//投递方式 M
            Map<String, String> uws = Tools.mapDicByCode(factory, "UWS");//投递方式 M
            Map<String, String> cmc = Tools.mapDicByCode(factory, "CMC");//投递方式 M
            Map<String, String> bjxs = Tools.mapDicByCode(factory, "BJXS");//投递方式 M

            WaterTypeMapper mapper = factory.getMapper(WaterTypeMapper.class);
            UserTypeMapper userTypeMapper = factory.getMapper(UserTypeMapper.class);

            WaterTypeQueryBean selectBean = new WaterTypeQueryBean();
            selectBean.setStatus(1);//只查询启用的
            selectBean.setWaterTypeNo("all");
            List<WaterTypeVO> waterTypeVOList = mapper.findWaterType(selectBean);
            List<String> waterTypeList=waterTypeVOList.stream().map(WaterTypeVO::getWaterTypeName).collect(Collectors.toList());


            //开户银行(购买方开户银行)
            List<SelectVO> openAccountBankList = factory.getMapper(BankMapper.class).bankSelect();
            List<String> openBankNameList=openAccountBankList.stream().map(SelectVO::getName).collect(Collectors.toList());

            List<BusinessAreaVo> businessAreaVoList = businessAreaMapper.selectList(userInfo.getCurWaterCode());
            List<String> businessAreaNameList = businessAreaVoList.stream().map(BusinessAreaVo::getAreaName).collect(Collectors.toList());

            String prefix = "工程报装-立户阶段-水表导出模板2";


            Workbook workbook = writer.getWorkbook();
            workbook.setSheetName(0, prefix);
            Sheet sheet1 = workbook.getSheetAt(0);
            //设置表头
            Iterator<String> iterator = headers.keySet().iterator();

            //cellStyle.setFont(font);
            int cellNum=0;
            ExcelUtils excelUtils = new ExcelUtils();
            while (iterator.hasNext()){

                String key = iterator.next();
                if (!list.get(0).containsKey(key)){
                    continue;
                }
                writer.addHeaderAlias(key,String.valueOf(headers.get(key)));



                writer.setColumnWidth(cellNum, 20);


                switch (key){
                    case "ctmTypeName":
                        String[] ctmTypes = Convert.toStrArray(ctt.values());
                        excelUtils.createDropDownListWithHiddenSheet(sheet1, 1, cellNum, 1000, cellNum, ctmTypes, workbook, "ctmTypes");
                        break;
                    case "certTypeName":
                        String[] cerTypes = Convert.toStrArray(idt.values());
                        excelUtils.createDropDownListWithHiddenSheet(sheet1, 1, cellNum, 1000, cellNum, cerTypes, workbook, "cerTypes");
                        break;
                    case "useWaterType":
                        String[] useWaterTypes=Convert.toStrArray(waterTypeList);
                        excelUtils.createDropDownListWithHiddenSheet(sheet1, 1, cellNum, 1000, cellNum, useWaterTypes, workbook, "useWaterTypes");
                        break;
                    case "creditLevelName":
                        String[] creditLevelNames=Convert.toStrArray(cdl.values());
                        excelUtils.createDropDownListWithHiddenSheet(sheet1, 1, cellNum, 1000, cellNum, creditLevelNames, workbook, "creditLevelNames");
                        break;
                    case "payWayName":
                        String[] payWayNames=Convert.toStrArray(bpw.values());
                        excelUtils.createDropDownListWithHiddenSheet(sheet1, 1, cellNum, 1000, cellNum, payWayNames, workbook, key+"s");
                        break;
                    case "accountTypeName":
                        String[] accountTypeNames=Convert.toStrArray(act.values());
                        excelUtils.createDropDownListWithHiddenSheet(sheet1, 1, cellNum, 1000, cellNum, accountTypeNames, workbook, key+"s");
                        break;
                    case "deliverWayName":
                        String[] deliverWayNames=Convert.toStrArray(SDW.values());
                        excelUtils.createDropDownListWithHiddenSheet(sheet1, 1, cellNum, 1000, cellNum, deliverWayNames, workbook, key+"s");
                        break;
                        //openBankNameList
                    case "invoiceBank":
                        String[] invoiceBanks=Convert.toStrArray(openBankNameList);
                        excelUtils.createDropDownListWithHiddenSheet(sheet1, 1, cellNum, 1000, cellNum, invoiceBanks, workbook, key+"s");
                        break;
                    case "vatFlagName":
                        excelUtils.createDropDownListWithHiddenSheet(sheet1, 1, cellNum, 1000, cellNum, vatFlagNames, workbook, key+"s");
                        break;
                    case "mergeInvoicingName":
                        excelUtils.createDropDownListWithHiddenSheet(sheet1, 1, cellNum, 1000, cellNum, vatFlagNames, workbook, key+"s");
                        break;
                    case "preInvoicingName":
                        excelUtils.createDropDownListWithHiddenSheet(sheet1, 1, cellNum, 1000, cellNum, vatFlagNames, workbook, key+"s");
                        break;
                    case "businessArea":
                        String[] businessAreas=Convert.toStrArray(businessAreaNameList);
                        excelUtils.createDropDownListWithHiddenSheet(sheet1, 1, cellNum, 1000, cellNum, businessAreas, workbook, key+"s");
                        break;
                    case "meterBjms":
                        String[] meterBjmss=Convert.toStrArray(bjms.values());
                        excelUtils.createDropDownListWithHiddenSheet(sheet1, 1, cellNum, 1000, cellNum, meterBjmss, workbook, key+"s");
                        break;
                    case "meterUse":
                        String[] meterUses=Convert.toStrArray(cmc.values());
                        excelUtils.createDropDownListWithHiddenSheet(sheet1, 1, cellNum, 1000, cellNum, meterUses, workbook, key+"s");
                        break;
                    case "useWaterObject":
                        String[] useWaterObjects=Convert.toStrArray(uws.values());
                        excelUtils.createDropDownListWithHiddenSheet(sheet1, 1, cellNum, 1000, cellNum, useWaterObjects, workbook, key+"s");
                        break;
                    case "meterBjxs":
                        String[] meterBjxss=Convert.toStrArray(bjxs.values());
                        excelUtils.createDropDownListWithHiddenSheet(sheet1, 1, cellNum, 1000, cellNum, meterBjxss, workbook, key+"s");
                        break;
                    case "userType":
                        List<SelectVO> userTypes = userTypeMapper.selectVo();
                        List<String> collect = userTypes.stream().map(SelectVO::getName).collect(Collectors.toList());
                        String[] userTypesArr = Convert.toStrArray(collect);
                        excelUtils.createDropDownListWithHiddenSheet(sheet1, 1, cellNum, 1000, cellNum, userTypesArr, workbook, key+"s");
                        break;

                    default:
                        break;

                }

                cellNum++;
            }

            String suffix = ".xls";


            //list.add(0,headers);
            //【ID1020929】【茂名水司】【报装】【工程报装-基础信息】水司反馈：下载模板打开数据表，下载下来得数据表数据存在错位；
            for (Map<String, Object> map : list) {
                MapDifference<String, Object> difference = Maps.difference(headers, map);

                Map<String, Object> map1 = difference.entriesOnlyOnRight();

                Set<String> keySet = map1.keySet();

                if (keySet.size()>0){
                    keySet.stream().forEach(x->map.remove(x));
                }

            }

            writer.write(list, true);
            //样式
            //设置样式
            StyleSet style = writer.getStyleSet();
            //设置普通单元格样式
            CellStyle cellStyle = style.getCellStyle();
            Font font = writer.createFont();
            font.setFontName("等线");
            font.setFontHeightInPoints((short) 11);
            cellStyle.setFont(font);
            cellStyle.setWrapText(true);


            //定义单元格背景色
            //第二个参数表示是否设置头部单元格背景
            style.setBackgroundColor(IndexedColors.WHITE, true);

            int index=0;
            Iterator<String> iterator2 = headers.keySet().iterator();

            while (iterator2.hasNext()){
                String key = iterator2.next();
                if (mandatoryMap.containsKey(key)&&mandatoryMap.get(key)==1){

                    Font font1 = workbook.createFont();
                    font1.setFontName("等线");
                    font1.setFontHeightInPoints((short) 11);

                    font1.setColor(IndexedColors.RED.getIndex());
                    Cell cell = sheet1.getRow(0).getCell(index);
                    CellStyle cellStyle1 = workbook.createCellStyle();
                    cellStyle1.setFont(font1);
                    cellStyle1.setAlignment(HorizontalAlignment.CENTER);
                    cellStyle1.setBorderRight(BorderStyle.THIN);
                    cell.setCellStyle(cellStyle1);


                }

                index++;
            }





            HttpHeaders header = new HttpHeaders();
            String prefixName= URLEncoder.encode(prefix,"UTF-8");
            header.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            header.setContentDispositionFormData("attachment", prefixName + suffix);

//        workbook.write(out);
//        out.close();

            writer.flush(out, true);
            // 关闭writer，释放内存
            //此处记得关闭输出Servlet流

            byte[] bytes = out.getBytes();
            return new ResponseEntity<byte[]>(bytes, header, HttpStatus.OK);
        } catch (Exception e) {
            log.error("立户模板导出失败: " + e.getMessage(), e);
            MessageBean<Object> messageBean = MessageBean.create(Constant.MESSAGE_INT_FAIL, "立户模板导出失败: " + e.getMessage(), null);
            ResponseEntity responseEntity = new ResponseEntity(messageBean, HttpStatus.INTERNAL_SERVER_ERROR);
            return responseEntity;
        }finally {
            //close包含了判空
            IoUtil.close(out);
            IoUtil.close(writer);
        }





    }
    private List<Map<String, Object>> getList(SessionFactory factory, UserInfoBean userInfo, RequestBean req){
        PjMeterQuery pjMeterQuery = JsonUtils.objectToPojo(req.getData(), PjMeterQuery.class);
        PjMeterMapper pjMeterMapper = factory.getMapper(PjMeterMapper.class);
        UserInfoMapper userInfoMapper = factory.getMapper(UserInfoMapper.class);
        OrgUserMapper orgUserMapper = factory.getMapper(OrgUserMapper.class);
        CtmInfoMapper ctmInfoMapper = factory.getMapper(CtmInfoMapper.class);
        AccountInfoMapper accountInfoMapper = factory.getMapper(AccountInfoMapper.class);
        UserFieldConfigMapper userFieldConfigMapper = factory.getMapper(UserFieldConfigMapper.class);
        PubAdminAreaMapper pubAdminAreaMapper = factory.getMapper(PubAdminAreaMapper.class);
        PjInfoMapper pjInfoMapper = factory.getMapper(PjInfoMapper.class);

        List<Map<String, Object>> result = new LinkedList<>();

        // 2. 查出所有的立户信息
        List<PjMeter> pjMeterList = pjMeterMapper.getList(pjMeterQuery);
        // 20220606: 如果立户数据不为空
        if (pjMeterList != null && pjMeterList.size() > 0) {
            // 2.1 查出工程编号
            String consultId = pjMeterList.get(0).getConsultId();
            PjInfoBean pjInfoBean = pjInfoMapper.selectById(consultId);
            String billNo = pjInfoBean.getBillNo();
            // 3. 查出对应的临时用户信息
            List<String> userInfoTempIdList = pjMeterList.stream().map(PjMeter::getUserInfoTempId).collect(Collectors.toList());
            UserInfoQueryBean userInfoQueryBean = new UserInfoQueryBean();
            userInfoQueryBean.setIdList(userInfoTempIdList);
            List<UserBean> userBeanList = userInfoMapper.getList(userInfoQueryBean, UserBean.USERTEMP);

            // 3. 查出对应的临时客户信息
            List<String> userCtmTempIdList = pjMeterList.stream().map(PjMeter::getUserCtmTempId).collect(Collectors.toList());
            List<CtmInfoBean> ctmInfoBeanList = ctmInfoMapper.getListByIdList(userCtmTempIdList, CtmInfoBean.CTMTEMP);
            // 4. 查出对应的临时账户信息
            List<String> userAccountTempIdList = pjMeterList.stream().map(PjMeter::getUserAccountTempId).collect(Collectors.toList());
            List<AccountInfoBean> accountInfoBeanList = accountInfoMapper.getListByIdList(userAccountTempIdList, AccountInfoBean.ACCOUNTTEMP);
            UserTypeMapper userTypeMapper = factory.getMapper(UserTypeMapper.class);
            // 5. 插入客户，账户，用户信息
            pjMeterList.forEach(pjMeter -> {
                Map<String, Object> detailMap = new LinkedHashMap<>();
                int i = pjMeterList.indexOf(pjMeter);
                UserBean userBean = userInfoMapper.getUserInfoById(pjMeter.getUserInfoTempId(), UserBean.USERTEMP);
                detailMap.put("userNo",userBean.getUserNo());
                detailMap.put("userType",userBean.getUserType());
                if (StringUtils.isNotBlank(userBean.getUserType())){
                    String userTypeName = userTypeMapper.getUserTypeNameById(userBean.getUserType());
                    detailMap.put("userType",userTypeName);
                }
                // 工程编号
                detailMap.put("billNo", billNo);

                // 6. 获取对应的ctmInfoBean: 插入顺序跟title方法中的顺序保持一致
                CtmInfoBean ctmInfoBean = null;
                // 单客户情况
                if (ctmInfoBeanList.size() == 1) {
                    ctmInfoBean = ctmInfoBeanList.get(0);
                } // 多客户情况
                else {
                    ctmInfoBean = ctmInfoBeanList.get(i);
                }
                // 6.1 certNo
                detailMap.put("certNo", ctmInfoBean.getCertNo());
                // 6.2 ctmName
                detailMap.put("ctmName", ctmInfoBean.getCtmName());
//                // 6.3 clientAddrName
//                String clientAddr = ctmInfoBean.getClientAddr();
//                if (StringUtils.isNotEmpty(clientAddr)) {
//                    String area = pubAdminAreaMapper.selectFullNameById(clientAddr);
//                    detailMap.put("clientAddrName", area);
//                } else {
//                    detailMap.put("clientAddrName", clientAddr);
//                }
                // 6.4 clientAddrDetail
                detailMap.put("clientAddrDetail", ctmInfoBean.getClientAddrDetail());
                // 6.5 ctmTypeName
                String ctmType = ctmInfoBean.getCtmType();
                if (StringUtils.isNotEmpty(ctmType)) {
                    String ctmTypeName = Tools.getDicNameByCodeAndValue(factory, "CTT", ctmType);
                    detailMap.put("ctmTypeName", ctmTypeName);
                } else {
                    detailMap.put("ctmTypeName", ctmType);
                }
                // 6.6 certTypeName
                String certType = ctmInfoBean.getCertType();
                if (StringUtils.isNotEmpty(certType)) {
                    String certTypeName = Tools.getDicNameByCodeAndValue(factory, "IDT", certType);
                    detailMap.put("certTypeName", certTypeName);
                } else {
                    detailMap.put("certTypeName", certType);
                }
                // 6.7 creditLevelName
                String creditLevel = ctmInfoBean.getCreditLevel();
                if (StringUtils.isNotEmpty(creditLevel)) {
                    String creditLevelName = Tools.getDicNameByCodeAndValue(factory, "CDL", creditLevel);
                    detailMap.put("creditLevelName", creditLevelName);
                } else {
                    detailMap.put("creditLevelName", creditLevel);
                }
                // 6.8 linkTel
                detailMap.put("linkTel", ctmInfoBean.getLinkTel());
                // 6.9 mobile
                detailMap.put("mobile", ctmInfoBean.getMobile());
                // 6.10 faxNumber
                detailMap.put("faxNumber", ctmInfoBean.getFaxNumber());

                // 7. 获取对应的accountInfoBean: 插入顺序跟title方法中的顺序保持一致
                AccountInfoBean accountInfoBean = null;
                // 单账户情况
                if (accountInfoBeanList.size() == 1) {
                    accountInfoBean = accountInfoBeanList.get(0);
                } // 多账户情况
                else {
                    accountInfoBean = accountInfoBeanList.get(i);
                }
                // 7.1 payWayName
                String payWay = accountInfoBean.getPayWay();
                if (StringUtils.isNotEmpty(payWay)) {
                    String payWayName = Tools.getDicNameByCodeAndValue(factory, "BPW", payWay);
                    detailMap.put("payWayName", payWayName);
                } else {
                    detailMap.put("payWayName", payWay);
                }
                // 7.2 accountTypeName
                String accountType = accountInfoBean.getAccountType();
                if (StringUtils.isNotEmpty(accountType)) {
                    String accountTypeName = Tools.getDicNameByCodeAndValue(factory, "ACT", accountType);
                    detailMap.put("accountTypeName", accountTypeName);
                } else {
                    detailMap.put("accountTypeName", accountType);
                }
                // 7.3 deliverWayName
                String deliverWay = accountInfoBean.getDeliverWay();
                if (StringUtils.isNotEmpty(deliverWay)) {
                    String deliverWayName = Tools.getDicNameByCodeAndValue(factory, "SDW", deliverWay);
                    detailMap.put("deliverWayName", deliverWayName);
                } else {
                    detailMap.put("deliverWayName", deliverWay);
                }
                // 7.4 deliverAddr
                detailMap.put("deliverAddr", accountInfoBean.getDeliverAddr());
                // 7.5 emailAddr
                detailMap.put("emailAddr", accountInfoBean.getEmailAddr());
                // 7.6 invoiceTitle
                detailMap.put("invoiceTitle", accountInfoBean.getInvoiceTitle());
                // 7.7 invoiceTax
                detailMap.put("invoiceTax", accountInfoBean.getInvoiceTax());
                // 7.8 invoiceAddr
                detailMap.put("invoiceAddr", accountInfoBean.getInvoiceAddr());
                // 7.9 invoiceLink
                detailMap.put("invoiceLink", accountInfoBean.getInvoiceLink());
                // 7.10 invoiceBank
                detailMap.put("invoiceBank", accountInfoBean.getInvoiceBank());
                // 7.11 invoiceAccount
                detailMap.put("invoiceAccount", accountInfoBean.getInvoiceAccount());
                // 7.12 vatFlagName
                String vatFlag = accountInfoBean.getVatFlag();
                if (StringUtils.isNotEmpty(vatFlag)) {
                    String vatFlagName = Tools.transferZeorOrOne(vatFlag);
                    detailMap.put("vatFlagName", vatFlagName);
                } else {
                    detailMap.put("vatFlagName", vatFlag);
                }
                // 7.13 preInvoicingName
                Integer preInvoicing = accountInfoBean.getPreInvoicing();
                if (preInvoicing != null) {
                    String preInvoicingName = Tools.transferZeorOrOne(preInvoicing.toString());
                    detailMap.put("preInvoicingName", preInvoicingName);
                } else {
                    detailMap.put("preInvoicingName", preInvoicing);
                }
                // 7.14 mergeInvoicingName
                Integer mergeInvoicing = accountInfoBean.getMergeInvoicing();
                if (mergeInvoicing != null) {
                    String mergeInvoicingName = Tools.transferZeorOrOne(mergeInvoicing.toString());
                    detailMap.put("mergeInvoicingName", mergeInvoicingName);
                } else {
                    detailMap.put("mergeInvoicingName", mergeInvoicing);
                }

                // 8. 获取对应的userBean: 目前是写死的。不知道怎么动态生成
                // 8.1 contractNo
                detailMap.put("contractNo", userBean.getContractNo());
                // 8.2 contractDate
                detailMap.put("contractDate", userBean.getContractDate());
                // 8.3 useTimeLimit
                detailMap.put("useTimeLimit", userBean.getUseTimeLimit());
                // 8.4 businessArea
                String businessArea = userBean.getBusinessArea();
                if (StringUtils.isNotEmpty(businessArea)) {
                    BusinessAreaMapper businessAreaMapper = factory.getMapper(BusinessAreaMapper.class);
                    String area = businessAreaMapper.findBusinessAreaById(userBean.getBusinessArea(), userInfo.getCurWaterCode());
                    detailMap.put("businessArea", area);
                } else {
                    detailMap.put("businessArea", businessArea);
                }
                // 8.5 stopWaterLinkMan
                detailMap.put("stopWaterLinkMan", userBean.getStopWaterLinkMan());
                // 8.6 stopWaterLinkMobile
                detailMap.put("stopWaterLinkMobile", userBean.getStopWaterLinkMobile());
                // 8.7 userGroupNo
                detailMap.put("userGroupNo", userBean.getUserGroupNo());
                // 8.8 comments
                detailMap.put("comments", userBean.getComments());
                // 8.9 meterNo
                detailMap.put("meterNo", userBean.getMeterNo());
//                // 8.10 clientContractAddr
//                String clientContractAddr = userBean.getClientContractAddr();
//                if (StringUtils.isNotEmpty(clientContractAddr)) {
//                    String area = pubAdminAreaMapper.selectFullNameById(clientContractAddr);
//                    detailMap.put("clientContractAddr", area);
//                } else {
//                    detailMap.put("clientContractAddr", clientContractAddr);
//                }
                // 8.11 clientContractAddrDetail
                detailMap.put("clientContractAddrDetail", userBean.getClientContractAddrDetail());
                // 8.12 meterBjms
                String meterBjms = userBean.getMeterBjms();
                if (StringUtils.isNotEmpty(meterBjms)) {
                    String meterBjmsName = Tools.getDicNameByCodeAndValue(factory, "BJMS", meterBjms);
                    detailMap.put("meterBjms", meterBjmsName);
                } else {
                    detailMap.put("meterBjms", meterBjms);
                }
                // 8.13 meterUse
                String meterUse = userBean.getMeterUse();
                if (StringUtils.isNotEmpty(meterUse)) {
                    String meterUseName = Tools.getDicNameByCodeAndValue(factory, "CMC", meterUse);
                    detailMap.put("meterUse", meterUseName);
                } else {
                    detailMap.put("meterUse", meterUse);
                }
                // 8.14 useWaterObject
                String useWaterObject = userBean.getUseWaterObject();
                if (StringUtils.isNotEmpty(useWaterObject)) {
                    String useWaterObjectName = Tools.getDicNameByCodeAndValue(factory, "UWS", useWaterObject);
                    detailMap.put("useWaterObject", useWaterObjectName);
                } else {
                    detailMap.put("useWaterObject", useWaterObject);
                }
                // 8.15 setupMeterDate
                detailMap.put("setupMeterDate", userBean.getSetupMeterDate());
                // 8.16 miicno
                detailMap.put("miicno", userBean.getMiicno());
                // 8.17 miljfje
                detailMap.put("miljfje", userBean.getMiljfje());
                // 8.18 quotaWater
                detailMap.put("quotaWater", userBean.getQuotaWater());
                // 8.19 concentratorNo
                detailMap.put("concentratorNo", userBean.getConcentratorNo());
                // 8.20 meterSite
                detailMap.put("meterSite", userBean.getMeterSite());
                // 8.21 meterBjxs
                String meterBjxs = userBean.getMeterBjxs();
                if (StringUtils.isNotEmpty(meterBjxs)) {
                    String meterBjxsName = Tools.getDicNameByCodeAndValue(factory, "BJXS", meterBjxs);
                    detailMap.put("meterBjxs", meterBjxsName);
                } else {
                    detailMap.put("meterBjxs", meterBjxs);
                }
                // 8.22 realEstateNo
                detailMap.put("realEstateNo", userBean.getRealEstateNo());
                // 8.23 bankCode
                detailMap.put("bankCode", userBean.getBankCode());
                // 8.24 bankSubAccount
                detailMap.put("bankSubAccount", userBean.getBankSubAccount());

                // 9. 固定的价格信息，也来源于userBean
                // 9.1 useWaterType
                String useWaterType = userBean.getUseWaterType();
                if (StringUtils.isNotEmpty(useWaterType)) {
                    WaterTypeMapper waterTypeMapper = factory.getMapper(WaterTypeMapper.class);
                    WaterTypeBean waterTypeBean = waterTypeMapper.findWaterTypeById(useWaterType);
                    detailMap.put("useWaterType", waterTypeBean.getWaterTypeName());
                } else {
                    detailMap.put("useWaterType", useWaterType);
                }
                // 9.2 prefStrategyId
                String prefStrategyId = userBean.getPrefStrategyId();
                if (StringUtils.isNotEmpty(prefStrategyId)) {
                    PrefStrategyMapper prefStrategyMapper = factory.getMapper(PrefStrategyMapper.class);
                    PrefStrategyBean prefStrategyBean = prefStrategyMapper.selectPrefStrategyDetailById(prefStrategyId);
                    detailMap.put("prefStrategyId", prefStrategyBean.getStrategyName());
                } else {
                    detailMap.put("prefStrategyId", prefStrategyId);
                }
                // 9.3 prefCertNo
                detailMap.put("prefCertNo", userBean.getPrefCertNo());
                // 9.4 prefBeginDate
                detailMap.put("prefBeginDate", userBean.getPrefBeginDate());
                // 9.5 prefEndDate
                detailMap.put("prefEndDate", userBean.getPrefEndDate());

                result.add(detailMap);
            });
        } // 20220606: 兼容立户数据为空
        else {
            // 10.1 获取billNo
            String consultId = pjMeterQuery.getConsultId();
            PjInfoBean pjInfoBean = pjInfoMapper.selectById(consultId);
            String billNo = pjInfoBean.getBillNo();
            // 10.2 放置billNo
            Map<String, Object> detailMap = new LinkedHashMap<>();
            detailMap.put("billNo", billNo);
            result.add(detailMap);
        }
        return result;
    }


    //组装动态标题
    public Map<String, Object> title(List<UserFieldBean> detail) {
        Map<String, Object> map = new LinkedHashMap<String, Object>();
        /**
         * 工程编号
         */
        map.put("billNo", "工程编号");

        /**
         * 客户信息
         */
        map.put("certNo", "客户证件号码");
        map.put("ctmName", "客户名称");
//        map.put("clientAddrName", "客户结构化地址");
        map.put("clientAddrDetail", "客户单元地址");
        map.put("ctmTypeName", "客户类型");
        map.put("certTypeName", "证件类型");
        map.put("creditLevelName", "信用等级");
        map.put("linkTel", "固定电话");
        map.put("mobile", "手机号码");
        map.put("faxNumber", "传真号码");
        /**
         * 账户信息
         */
        map.put("payWayName", "缴费方式");
        map.put("accountTypeName", "账户类型");
        map.put("deliverWayName", "投递方式");
        map.put("deliverAddr", "投递地址");
        map.put("emailAddr", "电子邮件");
        map.put("invoiceTitle", "单位名称");
        map.put("invoiceTax", "纳税人识别号");
        map.put("invoiceAddr", "联系地址");
        map.put("invoiceLink", "座机号码");
        map.put("invoiceBank", "开户银行");
        map.put("invoiceAccount", "银行账户");
        map.put("vatFlagName", "增值税标记");
        map.put("preInvoicingName", "预开票标记");
        map.put("mergeInvoicingName", "合并开票标记");
        /**
         * 动态获取用户信息（包括用户信息、用户-IC卡信息、用户-水表信息）
         */
        for (UserFieldBean userFieldBean : detail) {
            if (("装表地址").equals(userFieldBean.getFieldName())) {
//                map.put("clientContractAddr", "装表结构化地址");
                map.put("clientContractAddrDetail", "装表单元地址");
                continue;
            }
            map.put(userFieldBean.getFieldCode(), userFieldBean.getFieldName());
        }

        /**
         * 用户-价格信息
         */
        map.put("useWaterType", "用水类型");
        map.put("prefStrategyId", "优惠策略");
        map.put("prefCertNo", "优惠证件号码");
        map.put("prefBeginDate", "优惠策略开始日期");
        map.put("prefEndDate", "优惠策略结束日期");

        return map;
    }
}
